// nproxy.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "nproxy.h"


typedef struct
{
	BOOL				fInitialized;
	ICLRMetaHost        *pMetaHost;
	ICLRRuntimeInfo		*pRuntimeInfo;
	ICLRRuntimeHost		*pRuntimeHost;	
}CLR, *PCLR;

#define CHECK_CLR(code) if(!gHost.fInitialized)return(code)
CLR gHost = {FALSE, NULL, NULL, NULL};

int Fibonacci(int n)
{
	CHECK_CLR(0);

	HRESULT hr;
	DWORD dwValue;
	WCHAR pwzBuffer[128];

	wsprintfW(pwzBuffer, L"%d", n);
	hr = gHost.pRuntimeHost->ExecuteInDefaultAppDomain(
		L"CTVC.Platform.LoadTest.dll",
		L"CTVC.Platform.LoadTest.Common",
		L"Fibonacci",
		pwzBuffer,
		&dwValue);
	if(FAILED(hr))
	{
		wsprintfW(pwzBuffer, L"Failed to call Fibonacci(%d) with HRESULT=%d", n, hr);
		//MessageBoxW(0, pwzBuffer, L"Fibonacci", MB_OK | MB_ICONERROR);
		return 0;
	}
	else
	{
		wsprintfW(pwzBuffer, L"Fibonacci(%d)=%d", n, dwValue);
		//MessageBoxW(0, pwzBuffer, L"Fibonacci", MB_OK | MB_ICONINFORMATION);
		return dwValue;
	}
}





int InitializeCLR()
{
	if(gHost.fInitialized)
		return 0;

#define E(msg) if(FAILED(hr)){nError=1;goto __exit;}

	HRESULT hr;
	int nError = 0;

	gHost.pMetaHost		= NULL;
	gHost.pRuntimeInfo	= NULL;
	gHost.pRuntimeHost	= NULL;

	hr = CoInitialize(NULL);

	hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&(gHost.pMetaHost));
	E(L"Failed to CLRCreateInstance");

	hr = gHost.pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&(gHost.pRuntimeInfo));
	E(L"Failed to GetRuntime");

	hr = gHost.pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&(gHost.pRuntimeHost));
	E(L"Failed to GetInterface");

	hr = gHost.pRuntimeHost->Start();
	E(L"Failed to Start");

	gHost.fInitialized = TRUE;

__exit:
	return nError;
}

void UnInitializeCLR()
{
	if(!gHost.fInitialized)
		return;

	if(gHost.pRuntimeHost)
	{
		gHost.pRuntimeHost->Stop();
		gHost.pRuntimeHost->Release();
	}
	if(gHost.pRuntimeInfo)
		gHost.pRuntimeInfo->Release();
	if(gHost.pMetaHost)
		gHost.pMetaHost->Release();
	gHost.fInitialized = FALSE;

	CoUninitialize();
}

